//region 1.0 Date
/**
 * 获取当前Unix时间戳
 */
Date.prototype.time=function () {
    return Math.round(this.getTime() / 1000);
};



//endregion
//region 1.1 localStorage
var cache = {
};

cache.set = function(key, value, timeout) {
    var expireAt = timeout ? timeout : 0;
    if (expireAt > 0 ) {
        expireAt = (new Date()).time() + timeout
    }

    localStorage[key] = JSON.stringify({
        value:value,
        expireAt:expireAt,
    });
};

cache.delete = function() {
    for(var i=0; i < arguments.length; i++) {
        delete localStorage[i]
    }
};

cache.get = function(key) {
    if (typeof localStorage[key] == 'string') {
        var data=JSON.parse(localStorage[key]);
        if (data.expireAt < 1 || (new Date()).time() < data.expireAt) {
            return data.value;
        }
        cache.delete(key);
    }
    return false
};

cache.exists = function (key) {
    if (typeof localStorage[key] == 'string') {
        var data=JSON.parse(localStorage[key]);
        if (data.expireAt < 1 || (new Date()).time() < data.expireAt) {
            return true;
        }
    }

    this.delete(key);

    return false;
};


//endregion
//region 1.2 Rsa
var Rsa = function (privateKey, publicKey) {
    this.privateKey = new RSAKey();

    if(privateKey != "") {
        this.privateKey.readPrivateKeyFromPEMString(privateKey);
    }

    if(publicKey != "") {
        this.publicKey = KEYUTIL.getKey(publicKey);
    }
};

Rsa.prototype.sign = function(hashAlg, data) {
    var hSig = this.privateKey.sign(data, hashAlg);
    return linebrk(hSig, 64);
};

Rsa.prototype.verify = function (data, secretData) {
    return this.publicKey.verify(data, secretData);
};
//endregion

var Config = {
    http:{
        path:{
            login:"/admin/login",
            getRights:"/admin/rights"
        }
    },
    loginUrl:"/web/sign-in.html",
    homeUrl:"/web/index.html",
};

var Http = {
    NOT_ALLOW : 403,
    isRequest :{},
    request : function (data) {
        var that = this;
        if (this.isRequest[ data.url ]) {
            return;
        }
        this.isRequest[ data.url ] = true;
        var params = {};
        params.url = data.url;
        params.type = (typeof data.type == 'undefined') ? 'post' : data.type;
        if (params.type != 'get') {
            params.contentType = (typeof data.contentType == 'undefined') ? 'application/json' : data.contentType;
        }
        params.dataType = (typeof data.dataType == 'undefined') ? 'json' : data.dataType;
        params.data = (typeof data.data == 'undefined') ? {} : data.data;

        if(typeof params.data != "string" && params.contentType == 'application/json') {
            params.data = JSON.stringify(params.data)
        }

        params.error = (typeof data.error == "function") ? data.error : function(ret) {};

        params.complete = function(xhr, error){
            that.isRequest[ data.url ] = false;
            if (xhr.status == that.NOT_ALLOW) {
                var response = JSON.parse(xhr.responseText);
                Utils.toast.failed(response.msg);
                setTimeout(function() {
                    window.location.href = Config.loginUrl;
                }, 1500);
                return
            }
            if(xhr.responseText.length < 1 && xhr.status != 200) {
                Utils.toast.failed("服务器错误，请重试");
                return
            }
            var response = JSON.parse(xhr.responseText);

            switch (response.code) {
                case 200:
                    data.success(response.data);
                    return;
                case Http.NOT_ALLOW:
                    Utils.toast.failed(response.msg);
                    setTimeout(function() {
                        window.location.href = Config.loginUrl;
                    }, 1500);
                    return;
            }
            Utils.toast.failed(response.msg);
            params.error(response);
        };
        $.ajax(params);
    },
    post:function (url, params, success) {
        var err = null;
        if(arguments.length == 4) {
            err = arguments[3]
        }
        this.request({
            url:url,
            data:params,
            success:success,
            error:err,
        });
    },
    put:function (url, params, success) {
        var err = null;
        if(arguments.length == 4) {
            err = arguments[3]
        }
        this.request({
            url:url,
            type:'put',
            data:params,
            success:success,
            error:err,
        });
    },
    delete:function(url, success){
        var err = null;
        if(arguments.length == 3) {
            err = arguments[2]
        }
        this.request({
            url:url,
            type:'delete',
            success:success,
            error:err,
        });
    },
    get:function (url, success) {
        var err = null;
        if(arguments.length == 3) {
            err = arguments[2]
        }
        this.request({
            url:url,
            type:'get',
            success:success,
            error:err,
        });
    }
};

var Utils = {
    toast:{
        failed:function(msg, timeout) {
            timeout = timeout ? timeout : 1500;
            var toast = document.createElement('div');
            toast.setAttribute('class', 'toast-failed');
            toast.appendChild(document.createTextNode(msg));
            document.body.appendChild(toast);
            setTimeout(function () {
                document.body.removeChild(toast);
            }, timeout);
        },
        success:function(msg,  timeout) {
            timeout = timeout ? timeout : 1500;
            var toast = document.createElement('div');
            toast.setAttribute('class', 'toast-success');
            toast.appendChild(document.createTextNode(msg));
            document.body.appendChild(toast);
            setTimeout(function () {
                document.body.removeChild(toast);
            }, timeout);
        },
    },
    convert:{
        long2ip:function (uint32) {
            if (!isFinite(uint32)) {
                return false
            }
            return [uint32 >>> 24, uint32 >>> 16 & 0xFF, uint32 >>> 8 & 0xFF, uint32 & 0xFF].join('.')
        }
    }
};

var Element = {
    isBindConfirm : false,
    module:'<li class="has-sub" >\n' +
        '              <a class="sidenav-item-link" href="javascript:void(0)" data-toggle="collapse" data-target="#m-{{name}}"\n' +
        '                aria-expanded="false" aria-controls="{{name}}">\n' +
        '                <i class="mdi mdi-view-dashboard-outline"></i>\n' +
        '                <span class="nav-text">{{desc}}</span> <b class="caret"></b>\n' +
        '              </a>\n' +
        '              <ul class="collapse"  id="m-{{name}}"\n' +
        '                data-parent="#sidebar-menu">\n' +
        '                <div class="sub-menu">\n' +
        '                </div>\n' +
        '              </ul>\n' +
        '            </li>',
    controller:'<li >\n' +
        '                      <a class="sidenav-item-link" href="/web/{{module}}/{{name}}.html">\n' +
        '                        <span class="nav-text">{{desc}}</span>\n' +
        '                        <span class="badge badge-danger">{{tag}}</span>\n' +
        '                      </a>\n' +
        '                    </li>',
    Enter:function (selector, handler) {
        $(selector).keypress(function (e) {
            if (e.keyCode == 13) {
                handler(this);
            }
        });
    },
    getModule:function (module) {
        var moduleStr = this.module;
        moduleStr = moduleStr.replace(/{{name}}/g, module.Data.name).replace(/{{desc}}/g, module.Data.description);
        return $(moduleStr);
    },
    getController:function (module, controller) {
        var controllerStr = this.controller;
        controllerStr = controllerStr.replace(/{{module}}/g, module.Data.name).replace(/{{name}}/g, controller.Data.name).replace(/{{desc}}/g, controller.Data.description).replace(/{{tag}}/g, controller.Data.tag);
        return $(controllerStr)
    },
    confirm:function(msg, callback) {
        var modal = $('#confirm');
        modal.find('.modal-body').html(msg);
        modal.modal('show');

        $('#confirm-ok').off('click').on('click', function () {
            modal.modal('hide');
            callback();
        });
    },
    formatter:{
      badge:function(value) {
        var yes = '是';
        var no  = '否';
        if(arguments.length > 2) {
            yes = arguments[1];
            no  = arguments[2];
        }

        var color = 'danger';
        var text  = no;
        if(parseInt(value) == 1) {
            color = 'success';
            text  = yes;
        }
        return '<span class="badge badge-'+color+'">'+text+'</span>';
      },
      isOn:function(value) {
          var checked = "";
          if(value == 1) {
              checked = "checked"
          }
         return '<label class="switch switch-text switch-success switch-pill form-control-label">' +
             '<input type="checkbox" class="switch-input form-check-input" '+checked+'>' +
             '<span class="switch-label" data-on="启用" data-off="禁用"></span>' +
             '<span class="switch-handle"></span> </label>'
      },
      ip:function (value) {
          return Utils.convert.long2ip(value);
      },
      datetime:function (value) {
          if(typeof value == 'number') {
              value = value*1000
          }
          var date = new Date(value);
          var YY = date.getFullYear() + '-';
          var MM = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
          var DD = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate());
          var hh = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
          var mm = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
          var ss = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
          return YY + MM + DD +" "+hh + mm + ss;
      }
    },
};

var Store = {
    rightList :{},
    init : function(){
        this.initCommonEvent();
        this.getRightList();
    },
    initCommonEvent:function() {
        //禁用与启用
        $('#crud-index').delegate('.switch-input', 'change', function () {
            var checkbox = $(this);
            Http.post(Crud.getUpOrDownUrl()+'?id='+checkbox.parent().parent().parent().attr('item-id'), {
               value: checkbox.prop('checked') ? 1 : 0,
            }, function (ret) {
            }, function () {
                checkbox.prop('checked', !checkbox.prop('checked'))
            });
        });

        //查看详情
        $('#crud-index').delegate('.curd-opt.badge-success', 'click', function () {
            var id = $(this).parent().parent().attr('item-id');
            Http.get(Crud.getRoute()+'?id='+id, function (info) {
                Crud.renderInfo(info);
                $("#crud-info").modal('show');
            });
        });

        //添加
        $('#crud-create').on('click', function () {
            Crud.renderWrite();
            $("#crud-write").modal('show');
        });

        //编辑
        $('#crud-index').delegate('.curd-opt.badge-warning', 'click', function () {
            var id = $(this).parent().parent().attr('item-id');
            Http.get(Crud.getRoute()+'?id='+id, function (info) {
                Crud.renderWrite(info);
                $("#crud-write").modal('show');
            });
        });

        //删除
        $('#crud-index').delegate('.curd-opt.badge-danger', 'click', function () {
            var id = $(this).parent().parent().attr('item-id');
            Element.confirm('您确认要删除该条目吗？', function () {
               Http.delete(Crud.getRoute()+'?id='+id, function (ret) {
                   Utils.toast.success("删除成功", 1500);
                   setTimeout(function () {
                       window.location.reload();
                   }, 1500);
               })
            });
        });

        //保存
        $('#crud-write-ok').on('click', function () {
            var inputs = $('#crud-write').find('.modal-body input');
            var data = {};
            $.each(inputs, function (index, input) {
                var ele = $(input);
                var key = ele.attr('data-field');
                var value = 0;
                switch (ele.attr('type')) {
                   case 'checkbox':
                       if(ele.prop('checked')) {
                           value = 1;
                       }
                      break;
                   default:
                       value = ele.val();
                       break;
                }
               data[ key ] = value;
            });

            //insert
            if(data.id == '') {
                delete data['id'];
                Http.post(Crud.getRoute(), data, function () {
                    $('#crud-write').modal('hide');
                    $('#crud-war-msg').empty();
                    Utils.toast.success('添加成功', 1500);
                    setTimeout(function () {
                        window.location.reload();
                    }, 1500);
                }, function (result) {
                    $('#crud-war-msg').html(result.msg);
                });
                return
            }

            //update
            var id = data['id'];
            delete data['id'];
            Http.put(Crud.getRoute()+'?id='+id, data, function () {
                $('#crud-write').modal('hide');
                $('#crud-war-msg').empty();
                Utils.toast.success('修改成功', 1500);
                setTimeout(function () {
                    window.location.reload();
                }, 1500);
            }, function (result) {
                $('#crud-war-msg').html(result.msg);
            });
        });
    },
    getRightList : function () {
        var that = this;
        if(document.documentURI.indexOf("sign-in.html") < 0) {
            Http.request({
                type:"get",
                url:Config.http.path.getRights,
                success:function (ret) {
                    that.rightList = ret;
                    that.renderPage();
                }
            });
        }
    },
    renderPage:function () {
        var that = this;

        var admin = cache.get('admin');

        $("#h-username").html(admin.trueName);
        $('#h-admin').html(admin.userName+' <small class="pt-1">'+admin.trueName+'</small>');

        if(typeof that.rightList.Data != "object") {
            return;
        }

        var root = that.rightList.Data;
        $(".brand-name").html(encodeURIComponent(root.description));

        if(this.rightList.Children.length < 1) {
            return;
        }

        var nav = $("#sidebar-menu");
        $.each(that.rightList.Children, function(index, mod) {
            var module = Element.getModule(mod);
            if(mod.Children.length > 0) {
                $.each(mod.Children, function(i, ctr){
                    var controller = Element.getController(mod, ctr);
                    module.find('.sub-menu').append(controller);
                });
            }
            module.appendTo(nav)
        });
    },
};

var Crud = {
    getRoute:function() {
        var currentUri =document.documentURI;
        currentUri = currentUri.replace('/web', '/admin');
        return currentUri.substr(0, currentUri.lastIndexOf('.'))
    },
    getIndexUrl:function() {
        return this.getRoute()+"/index"
    },
    getUpOrDownUrl:function() {
        return this.getRoute()+'/up-or-down';
    },
    init : function () {
        var that = this;
        Http.get(this.getIndexUrl(), function (result) {
            if(result.list.length < 1) {
                return
            }

            var tbody = $('#crud-index');
            $.each(result.list, function (index, item) {
                tbody.append(that.renderItem(item));
            });
        })
    }
};

$(document).ready(function () {
    Store.init();

    if(typeof Store.initPage == 'function') {
        Store.initPage();
    }
});